MCP Server Generator for Smithery (mcp-forge).md•19.7 kB
<img src="https://r2cdn.perplexity.ai/pplx-full-logo-primary-dark%402x.png" class="logo" width="120"/>
#
---
# MCP Server Generator for Smithery (mcp-forge)
This document provides the complete setup for creating a powerful MCP server that generates other MCP servers for Smithery, with seamless integration into Cursor IDE.
## Project Structure
```
mcp-forge/
├── src/
│ ├── index.js
│ ├── templates/
│ │ ├── basic.js
│ │ ├── web-search.js
│ │ └── database.js
├── Dockerfile
├── smithery.yaml
├── package.json
└── README.md
```
## Implementation Files
### 1. package.json
```json
{
"name": "@your-username/mcp-forge",
"version": "1.0.0",
"description": "MCP server for generating other MCP servers in Smithery",
"main": "src/index.js",
"type": "module",
"scripts": {
"start": "node src/index.js"
},
"keywords": ["mcp", "smithery", "generator", "cursor"],
"author": "Your Name",
"license": "MIT",
"dependencies": {
"@modelcontextprotocol/sdk": "^0.1.0",
"fs-extra": "^11.1.1",
"lodash": "^4.17.21"
}
}
```
### 2. src/index.js
```javascript
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import fs from 'fs-extra';
import path from 'path';
import { fileURLToPath } from 'url';
import { createBasicTemplate } from './templates/basic.js';
import { createWebSearchTemplate } from './templates/web-search.js';
import { createDatabaseTemplate } from './templates/database.js';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
// Create a new MCP server
const server = new Server(
{ name: "mcp-forge", version: "1.0.0" },
{
capabilities: {
tools: {
// Tool 1: Generate a new MCP server
generate_mcp_server: {
description: "Generates a new MCP server with the specified configuration",
parameters: {
type: "object",
properties: {
name: {
type: "string",
description: "Name of the MCP server"
},
template: {
type: "string",
enum: ["basic", "web-search", "database"],
description: "Template to use for the MCP server"
},
outputDir: {
type: "string",
description: "Directory to output the generated MCP server"
}
},
required: ["name", "template", "outputDir"]
},
handler: async (params) => {
const { name, template, outputDir } = params;
try {
// Create output directory if it doesn't exist
await fs.ensureDir(outputDir);
let templateFn;
switch (template) {
case "basic":
templateFn = createBasicTemplate;
break;
case "web-search":
templateFn = createWebSearchTemplate;
break;
case "database":
templateFn = createDatabaseTemplate;
break;
default:
templateFn = createBasicTemplate;
}
const files = templateFn(name);
// Write files
for (const [filePath, content] of Object.entries(files)) {
await fs.writeFile(path.join(outputDir, filePath), content);
}
return {
success: true,
message: `MCP server "${name}" has been generated in ${outputDir}`,
files: Object.keys(files)
};
} catch (error) {
return {
success: false,
error: error.message
};
}
}
},
// Tool 2: Get Cursor integration config
get_cursor_integration: {
description: "Generates the integration code for Cursor IDE",
parameters: {
type: "object",
properties: {
packageName: {
type: "string",
description: "NPM package name of the MCP server"
},
config: {
type: "object",
description: "Configuration object for the MCP server"
}
},
required: ["packageName"]
},
handler: async (params) => {
const { packageName, config = {} } = params;
const configString = JSON.stringify(config).replace(/"/g, '\\"');
const cursorConfig = {
command: "npx",
args: [
"-y",
"@smithery/cli@latest",
"run",
packageName,
"--config",
`"${configString}"`
]
};
const mcpJson = {
mcpServers: {
[packageName.split('/').pop()]: cursorConfig
}
};
return {
mcpJson: JSON.stringify(mcpJson, null, 2),
commandLine: `npx -y @smithery/cli@latest run ${packageName} --config "${configString}"`,
instructions: "Add this to your ~/.cursor/mcp.json file to integrate with Cursor IDE"
};
}
},
// Tool 3: Deploy to Smithery
deploy_to_smithery: {
description: "Provides instructions for deploying the MCP server to Smithery",
parameters: {
type: "object",
properties: {
repoUrl: {
type: "string",
description: "GitHub repository URL of the MCP server"
}
},
required: ["repoUrl"]
},
handler: async (params) => {
const { repoUrl } = params;
return {
steps: [
"1. Push your code to GitHub repository: " + repoUrl,
"2. Visit https://smithery.ai/dashboard",
"3. Click 'Deploy New Server'",
"4. Enter your repository URL",
"5. Follow the deployment instructions"
],
note: "Ensure your repository has a valid Dockerfile and smithery.yaml at the root"
};
}
}
}
}
}
);
// Start the server with stdio transport
const transport = new StdioServerTransport();
await server.connect(transport);
```
### 3. src/templates/basic.js
```javascript
export function createBasicTemplate(name) {
return {
'package.json': `{
"name": "@your-username/${name}",
"version": "1.0.0",
"description": "MCP server for ${name}",
"main": "index.js",
"type": "module",
"scripts": {
"start": "node index.js"
},
"keywords": ["mcp", "smithery"],
"author": "Your Name",
"license": "MIT",
"dependencies": {
"@modelcontextprotocol/sdk": "^0.1.0"
}
}`,
'index.js': `import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
// Create a new MCP server
const server = new Server(
{ name: "${name}", version: "1.0.0" },
{
capabilities: {
tools: {
example_tool: {
description: "An example tool",
parameters: {
type: "object",
properties: {
input: {
type: "string",
description: "Input parameter"
}
},
required: ["input"]
},
handler: async (params) => {
return { result: \`Processed: \${params.input}\` };
}
}
}
}
}
);
// Start the server with stdio transport
const transport = new StdioServerTransport();
await server.connect(transport);
`,
'Dockerfile': `FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
CMD ["node", "index.js"]
`,
'smithery.yaml': `startCommand:
type: stdio
configSchema:
type: object
properties:
exampleConfig:
type: string
description: Example configuration parameter
required: []
commandFunction: |
function generateCommand(config) {
return {
command: "node",
args: ["index.js"],
env: {}
};
}
`
};
}
```
### 4. src/templates/web-search.js
```javascript
export function createWebSearchTemplate(name) {
return {
'package.json': `{
"name": "@your-username/${name}",
"version": "1.0.0",
"description": "Web search MCP server",
"main": "index.js",
"type": "module",
"scripts": {
"start": "node index.js"
},
"keywords": ["mcp", "smithery", "web-search"],
"author": "Your Name",
"license": "MIT",
"dependencies": {
"@modelcontextprotocol/sdk": "^0.1.0",
"node-fetch": "^3.3.2"
}
}`,
'index.js': `import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import fetch from 'node-fetch';
// Create a new MCP server
const server = new Server(
{ name: "${name}", version: "1.0.0" },
{
capabilities: {
tools: {
web_search: {
description: "Search the web",
parameters: {
type: "object",
properties: {
query: {
type: "string",
description: "Search query"
},
limit: {
type: "number",
description: "Maximum number of results"
}
},
required: ["query"]
},
handler: async (params) => {
const { query, limit = 5 } = params;
const apiKey = process.env.SEARCH_API_KEY;
if (!apiKey) {
return {
error: "API key not provided. Set SEARCH_API_KEY environment variable."
};
}
try {
// Implement your search API call here
// This is a placeholder
const response = await fetch(\`https://api.example.com/search?q=\${encodeURIComponent(query)}&limit=\${limit}\`, {
headers: {
'Authorization': \`Bearer \${apiKey}\`
}
});
const data = await response.json();
return {
results: data.results || []
};
} catch (error) {
return {
error: error.message
};
}
}
}
}
}
}
);
// Start the server with stdio transport
const transport = new StdioServerTransport();
await server.connect(transport);
`,
'Dockerfile': `FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
CMD ["node", "index.js"]
`,
'smithery.yaml': `startCommand:
type: stdio
configSchema:
type: object
properties:
searchApiKey:
type: string
description: API key for the search service
required: ["searchApiKey"]
commandFunction: |
function generateCommand(config) {
return {
command: "node",
args: ["index.js"],
env: {
SEARCH_API_KEY: config.searchApiKey
}
};
}
`
};
}
```
### 5. src/templates/database.js
```javascript
export function createDatabaseTemplate(name) {
return {
'package.json': `{
"name": "@your-username/${name}",
"version": "1.0.0",
"description": "Database MCP server",
"main": "index.js",
"type": "module",
"scripts": {
"start": "node index.js"
},
"keywords": ["mcp", "smithery", "database"],
"author": "Your Name",
"license": "MIT",
"dependencies": {
"@modelcontextprotocol/sdk": "^0.1.0",
"pg": "^8.11.0"
}
}`,
'index.js': `import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import pg from 'pg';
const { Pool } = pg;
// Initialize database connection
let pool;
// Create a new MCP server
const server = new Server(
{ name: "${name}", version: "1.0.0" },
{
capabilities: {
tools: {
run_query: {
description: "Run SQL query on database",
parameters: {
type: "object",
properties: {
query: {
type: "string",
description: "SQL query to execute"
},
params: {
type: "array",
description: "Query parameters",
items: {
type: "string"
}
}
},
required: ["query"]
},
handler: async (params) => {
const { query, params: queryParams = [] } = params;
if (!pool) {
const connectionString = process.env.DATABASE_URL;
if (!connectionString) {
return {
error: "Database connection string not provided. Set DATABASE_URL environment variable."
};
}
pool = new Pool({
connectionString
});
}
try {
const result = await pool.query(query, queryParams);
return {
rows: result.rows,
rowCount: result.rowCount
};
} catch (error) {
return {
error: error.message
};
}
}
},
describe_table: {
description: "Describe database table structure",
parameters: {
type: "object",
properties: {
tableName: {
type: "string",
description: "Name of the table to describe"
}
},
required: ["tableName"]
},
handler: async (params) => {
const { tableName } = params;
if (!pool) {
const connectionString = process.env.DATABASE_URL;
if (!connectionString) {
return {
error: "Database connection string not provided. Set DATABASE_URL environment variable."
};
}
pool = new Pool({
connectionString
});
}
try {
const query = \`
SELECT column_name, data_type, is_nullable, column_default
FROM information_schema.columns
WHERE table_name = $1
ORDER BY ordinal_position
\`;
const result = await pool.query(query, [tableName]);
return {
columns: result.rows,
count: result.rowCount
};
} catch (error) {
return {
error: error.message
};
}
}
}
}
}
}
);
// Start the server with stdio transport
const transport = new StdioServerTransport();
await server.connect(transport);
`,
'Dockerfile': `FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
CMD ["node", "index.js"]
`,
'smithery.yaml': `startCommand:
type: stdio
configSchema:
type: object
properties:
databaseUrl:
type: string
description: PostgreSQL connection string
required: ["databaseUrl"]
commandFunction: |
function generateCommand(config) {
return {
command: "node",
args: ["index.js"],
env: {
DATABASE_URL: config.databaseUrl
}
};
}
`
};
}
```
### 6. Dockerfile
```dockerfile
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
CMD ["node", "src/index.js"]
```
### 7. smithery.yaml
```yaml
startCommand:
type: stdio
configSchema:
type: object
properties:
smitheryApiToken:
type: string
description: Smithery API token for deployment operations
required: []
commandFunction: |
function generateCommand(config) {
return {
command: "node",
args: ["src/index.js"],
env: {
SMITHERY_API_TOKEN: config.smitheryApiToken || ""
}
};
}
```
## Integration with Cursor IDE
To integrate this MCP server with Cursor IDE, add the following configuration to your global mcp.json file:
```json
{
"mcpServers": {
"mcp-forge": {
"command": "npx",
"args": [
"-y",
"@smithery/cli@latest",
"run",
"@your-username/mcp-forge",
"--config",
"{}"
]
}
}
}
```
## Usage in Cursor
Once integrated, you can use the following tools from Cursor:
1. `generate_mcp_server` - Generate a new MCP server from a template
2. `get_cursor_integration` - Get integration code for Cursor IDE
3. `deploy_to_smithery` - Get instructions for deploying to Smithery
## Deployment Steps
1. Create the project structure as outlined above
2. Implement the provided code files
3. Test locally using `npm start`
4. Push to GitHub
5. Deploy on Smithery:
- Go to Smithery dashboard
- Click "Deploy New Server"
- Enter your GitHub repository URL
- Follow deployment instructions
6. After deployment, integrate with Cursor using the provided configuration
This MCP server enables rapid development of other MCP servers by providing templates, configuration assistance, and deployment guidance, all within the Cursor IDE environment.
<div style="text-align: center">⁂</div>
[^1]: https://pplx-res.cloudinary.com/image/upload/v1742942047/user_uploads/ZyqsNIkkkuKueqU/image.jpg
[^2]: https://pplx-res.cloudinary.com/image/upload/v1742942066/user_uploads/RpFOwYlSkfbzvbh/image.jpg
[^3]: https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/17146172/bca66741-9637-4a7f-b0b7-3e88bf3e9130/mcp.rules.md
[^4]: https://pplx-res.cloudinary.com/image/upload/v1742944001/user_uploads/uThfdtgctaUXHgK/image.jpg
[^5]: https://cursor101.com/article/cursor-what-is-mcp
[^6]: https://www.youtube.com/watch?v=RCFe1L9qm3E
[^7]: https://www.youtube.com/watch?v=8m-O_KiHRjk
[^8]: https://mcp.so/server/unreal-mcp-server/AlexKissiJr
[^9]: https://github.com/daniel-lxs/mcp-server-starter
[^10]: https://smithery.ai/docs/config
[^11]: https://www.reddit.com/r/cursor/comments/1jbdrof/how_to_install_mcp_tools_in_cursor_ide/
[^12]: https://glama.ai/mcp/servers/tg4ugmp8jr
[^13]: https://smithery.ai/new
[^14]: https://github.com/kirill-markin/example-mcp-server
[^15]: https://glama.ai/mcp/servers/rbgsskqcgb/blob/main/smithery.yaml
[^16]: https://docs.cursor.com/context/model-context-protocol
[^17]: https://jigsawstack.com/blog/jigsawstack-mcp-servers
[^18]: https://www.apideck.com/blog/unlocking-ai-potential-how-to-quickly-set-up-a-cursor-mcp-server
[^19]: https://www.youtube.com/watch?v=WPdaWUnm2ik
[^20]: https://glama.ai/mcp/servers/@chrisboden/mcp_template
[^21]: https://forum.cursor.com/t/how-to-use-mcp-server/50064
[^22]: https://smithery.ai
[^23]: https://smithery.ai/server/@nicknochnack/BuildMCPServer
[^24]: https://www.youtube.com/watch?v=2GHRDoFquOo